<template>
  <div class="line-connector" ref="container">
    <svg ref="svg" class="absolute top-0 left-0 w-full h-full" :style="{ zIndex: zIndex }">
      <g v-for="(line, index) in lines" :key="index">
        <path 
          :d="getLinePath(line.from, line.to, line.type)" 
          :stroke="line.stroke || '#3b82f6'" 
          :stroke-width="line.strokeWidth || 2" 
          :stroke-dasharray="line.dashArray || ''"
          :fill="line.fill || 'none'"
          class="transition-all duration-300"
        />
        <marker 
          v-if="line.arrow"
          :id="'arrow-' + index"
          markerWidth="10"
          markerHeight="10"
          refX="9"
          refY="3"
          orient="auto"
          markerUnits="strokeWidth"
        >
          <path d="M0,0 L0,6 L9,3 z" :fill="line.stroke || '#3b82f6'" />
        </marker>
      </g>
    </svg>
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'LineConnector',
  props: {
    zIndex: {
      type: Number,
      default: 1
    }
  },
  data() {
    return {
      lines: [],
      observer: null
    };
  },
  mounted() {
    // 监听DOM变化，以便更新连线
    this.observeDOMChanges();
    
    // 监听窗口大小变化，更新连线
    window.addEventListener('resize', this.updateAllLines);
  },
  beforeDestroy() {
    if (this.observer) {
      this.observer.disconnect();
    }
    window.removeEventListener('resize', this.updateAllLines);
  },
  methods: {
    /**
     * 添加一条连线
     * @param {Object} options - 连线配置
     * @param {string} options.from - 起点元素ID
     * @param {string} options.to - 终点元素ID
     * @param {string} [options.type='straight'] - 连线类型：straight, bezier
     * @param {string} [options.stroke='#3b82f6'] - 线条颜色
     * @param {number} [options.strokeWidth=2] - 线条宽度
     * @param {string} [options.dashArray=''] - 虚线样式
     * @param {boolean} [options.arrow=false] - 是否显示箭头
     * @param {string} [options.fill='none'] - 填充颜色
     * @returns {number} - 连线ID
     */
    addLine(options) {
      const lineId = this.lines.length;
      this.lines.push({
        id: lineId,
        ...options
      });
      this.$nextTick(() => this.updateLine(lineId));
      return lineId;
    },
    
    /**
     * 更新一条连线
     * @param {number} lineId - 连线ID
     */
    updateLine(lineId) {
      const line = this.lines[lineId];
      if (!line) return;
      
      const fromEl = document.getElementById(line.from);
      const toEl = document.getElementById(line.to);
      
      if (!fromEl || !toEl) {
        console.warn(`Element with ID ${line.from} or ${line.to} not found`);
        return;
      }
      
      // 获取元素位置
      const fromRect = fromEl.getBoundingClientRect();
      const toRect = toEl.getBoundingClientRect();
      const containerRect = this.$refs.container.getBoundingClientRect();
      
      // 计算相对于容器的坐标
      const from = {
        x: fromRect.left + fromRect.width / 2 - containerRect.left,
        y: fromRect.top + fromRect.height / 2 - containerRect.top
      };
      
      const to = {
        x: toRect.left + toRect.width / 2 - containerRect.left,
        y: toRect.top + toRect.height / 2 - containerRect.top
      };
      
      // 更新连线数据
      this.$set(this.lines, lineId, {
        ...line,
        from,
        to
      });
    },
    
    /**
     * 更新所有连线
     */
    updateAllLines() {
      this.lines.forEach((_, index) => this.updateLine(index));
    },
    
    /**
     * 移除一条连线
     * @param {number} lineId - 连线ID
     */
    removeLine(lineId) {
      this.lines.splice(lineId, 1);
    },
    
    /**
     * 移除所有连线
     */
    removeAllLines() {
      this.lines = [];
    },
    
    /**
     * 获取连线的路径数据
     * @param {Object} from - 起点坐标 {x, y}
     * @param {Object} to - 终点坐标 {x, y}
     * @param {string} type - 连线类型
     * @returns {string} - SVG路径数据
     */
    getLinePath(from, to, type = 'straight') {
      if (!from || !to) return '';
      
      if (type === 'bezier') {
        const controlPointDistance = Math.abs(to.x - from.x) / 2;
        return `M ${from.x},${from.y} C ${from.x + controlPointDistance},${from.y} ${to.x - controlPointDistance},${to.y} ${to.x},${to.y}`;
      }
      
      // 默认使用直线
      return `M ${from.x},${from.y} L ${to.x},${to.y}`;
    },
    
    /**
     * 监听DOM变化，以便自动更新连线
     */
    observeDOMChanges() {
      this.observer = new MutationObserver(() => {
        this.$nextTick(() => this.updateAllLines());
      });
      
      this.observer.observe(this.$refs.container, {
        childList: true,
        subtree: true,
        attributes: true,
        characterData: true
      });
    }
  }
}
</script>

<style scoped>
.line-connector {
  position: relative;
  min-height: 100px;
}
</style>  